package cn.wei.sdd.core.service.impl;

import cn.wei.common.exception.Assert;
import cn.wei.common.result.ResponseEnum;
import cn.wei.common.utils.MD5;
import cn.wei.sdd.base.dto.SmsDTO;
import cn.wei.sdd.base.util.JwtUtils;
import cn.wei.sdd.core.enums.ExamineStatusEnum;
import cn.wei.sdd.core.mapper.ExamineMapper;
import cn.wei.sdd.core.mapper.OrdersMapper;
import cn.wei.sdd.core.mapper.UserAccountMapper;
import cn.wei.sdd.core.pojo.entity.Examine;
import cn.wei.sdd.core.pojo.entity.User;
import cn.wei.sdd.core.mapper.UserMapper;
import cn.wei.sdd.core.pojo.entity.UserAccount;
import cn.wei.sdd.core.pojo.query.UserQuery;
import cn.wei.sdd.core.pojo.vo.*;
import cn.wei.sdd.core.service.OrderService;
import cn.wei.sdd.core.service.TakeMoneyRecordService;
import cn.wei.sdd.core.service.UserService;
import cn.wei.sdd.rabbitutils.constant.MQConst;
import cn.wei.sdd.rabbitutils.service.MQService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author Wei
 * @since 2021-09-22
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserAccountMapper userAccountMapper;

    @Resource
    private ExamineMapper examineMapper;

    @Resource
    private MQService mqService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private OrderService orderService;

    @Resource
    private TakeMoneyRecordService takeMoneyRecordService;



    @Override
    public Boolean selectUserByOpenid(String openid) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("openid",openid);
        User user = baseMapper.selectOne(userQueryWrapper);
        if (user==null){
            return false;
        }else{
            return true;
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addWxUser(String openid) {
        User user = new User();
        user.setOpenid(openid);
        user.setUserName("wxUser");
        baseMapper.insert(user);

        //创建会员账户
        UserAccount userAccount = new UserAccount();
        userAccount.setUserId(user.getId());
        userAccount.setUserType(UserAccount.USERTYPE);
        userAccountMapper.insert(userAccount);
    }

    @Override
    public String getToken(String openid) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("openid",openid);
        User user = baseMapper.selectOne(userQueryWrapper);
         return JwtUtils.createToken(user.getId(), user.getUserName(), String.valueOf(user.getUserType()));

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateInfo(UserVO userVo, Long userId) {
        User user = new User();
        user.setId(userId);
        user.setUserName(userVo.getUserName());
        user.setNickName(userVo.getNickName());
        user.setMobile(userVo.getMobile());
        user.setHeadImg(userVo.getHeadImg());

        baseMapper.updateById(user);
    }

    @Override
    public IPage<User> listPage(Page<User> pageParam, UserQuery userQuery) {
        if (userQuery==null){
            return  baseMapper.selectPage(pageParam, null);
        }

        String mobile = userQuery.getMobile();
        Integer status = userQuery.getStatus();
        Integer userType = userQuery.getUserType();

        //eq()有个重载方法，如果前面的为true，就组装后面的条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq(StringUtils.isNotBlank(mobile),"mobile",mobile)
                .eq(status!=null,"status",status)
                .eq(userType!=null,"user_type",userType);

        return baseMapper.selectPage(pageParam,queryWrapper);

    }

    @Override
    public void lock(Long id, Integer status) {
        User user = new User();
        user.setId(id);
        user.setStatus(status);
        baseMapper.updateById(user);
    }

    @Override
    public Boolean checkMobile(String mobile) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("mobile",mobile);

        Integer count = baseMapper.selectCount(userQueryWrapper);
        return count>0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(RegisterVO registerVO) {
        //添加到用户表
        User user = new User();
        System.out.println(registerVO.getUserName());
        user.setUserName(registerVO.getUserName());
        user.setUserType(Math.toIntExact(User.Recycler));
        String mobile = registerVO.getMobile();
        user.setMobile(mobile);
        user.setHeadImg(User.USER_AVATAR);
        user.setPassword(MD5.encrypt(mobile.substring(mobile.length() - 6)));//密码为手机号后六位
        user.setExamineStatus(Examine.NOT_APPROVED);
        user.setStatus(User.STATUS_LOCKED);
        baseMapper.insert(user);

        //添加申请记录
        Examine examine = new Examine();
        examine.setUserId(user.getId());
        examine.setAge(registerVO.getAge());
        examine.setSex(registerVO.getSex());
        examine.setUserName(registerVO.getUserName());
        examine.setMobile(registerVO.getMobile());
        examine.setIdCard(registerVO.getIdCard());
        examine.setIdCard1(registerVO.getIdCard1());
        examine.setIdCard2(registerVO.getIdCard2());
        examine.setStatus(ExamineStatusEnum.AUTH_RUN.getStatus());
        examineMapper.insert(examine);

    }

    @Override
    public BigDecimal getPercentByUserId(Long userId) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("id",userId).eq("user_type",User.Recycler);
        User user = baseMapper.selectOne(userQueryWrapper);
        return user.getPercent();
    }

    @Override
    public UserIndexInfoVO getUserIndexInfo(Integer userType, Long userId) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();

        //查询用户信息
        userQueryWrapper.eq("user_type",userType)
                .eq("id",userId);
        User user = baseMapper.selectOne(userQueryWrapper);

        //查询用户账户信息
        QueryWrapper<UserAccount> userAccountQueryWrapper = new QueryWrapper<>();
        userAccountQueryWrapper.eq("user_type",userType)
                .eq("user_id",userId);
        UserAccount userAccount = userAccountMapper.selectOne(userAccountQueryWrapper);


        //设置信息
        UserIndexInfoVO infoVO = new UserIndexInfoVO();
        infoVO.setRecoveryNumber(user.getRecoveryNumber());
        infoVO.setRecoveryWeight(user.getRecoveryWeight());
        infoVO.setAmount(userAccount.getAmount());
        infoVO.setTotalShouyi(userAccount.getTotalShouyi());

        return infoVO;
    }

    @Override
    public UserInfoVO recyclerLogin(LoginVO loginVO) {
        String mobile = loginVO.getUserName();
        String password = loginVO.getPassword();

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("mobile",mobile)
                .eq("user_type",User.Recycler);
        User user = baseMapper.selectOne(userQueryWrapper);
        //判断用户是否存在
        Assert.notNull(user, ResponseEnum.LOGIN_USER_ERROR);

        //判断密码是否正确
        Assert.equals(MD5.encrypt(password),user.getPassword(),ResponseEnum.LOGIN_PASSWORD_ERROR);


        //判断是否禁用
        Assert.equals(User.STATUS_NORMAL,user.getStatus(),ResponseEnum.LOGIN_LOKED_ERROR);


        //生成token
        String token = JwtUtils.createToken(user.getId(), user.getUserName(), String.valueOf(user.getUserType()));

        //组装数据
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setHeadImg(user.getHeadImg());
        userInfoVO.setUserName(user.getUserName());
        userInfoVO.setMobile(user.getMobile());
        userInfoVO.setToken(token);

        return userInfoVO;
    }

    @Override
    public void bingMobile(String mobile, Long userId, String code) {

        //验证码是否正确

        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userUpdateWrapper.eq("id",userId).set("mobile",mobile);
        baseMapper.update(null,userUpdateWrapper);

        //发消息
        SmsDTO smsDTO = new SmsDTO();
        smsDTO.setMobile(mobile);
        smsDTO.setMessage("绑定手机号成功");
        log.info("绑定手机号成功");
        mqService.sendMessage(
                MQConst.EXCHANGE_TOPIC_SMS,
                MQConst.ROUTING_SMS_ITEM,
                smsDTO
        );
        System.out.println("绑定手机号成功");
    }

    @Override
    public String getMobileByUserid(Long userId) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("id",userId);
        User user = baseMapper.selectOne(userQueryWrapper);
        return user.getMobile();
    }

    @Override
    public AdminHomeVO getAdminHomeInfo() {
        AdminHomeVO adminHomeVO = new AdminHomeVO();
        int customerCount = userMapper.selectCount(new QueryWrapper<User>().eq("user_type", User.USER));
        int recyclerCount = userMapper.selectCount(new QueryWrapper<User>().eq("user_type", User.Recycler));
        int orderCount = orderService.count();
        BigDecimal cashOutCount = takeMoneyRecordService.getTakeMoneyCount();
        adminHomeVO.setCustomerCount(customerCount);
        adminHomeVO.setRecyclerCount(recyclerCount);
        adminHomeVO.setOrderCount(orderCount);
        adminHomeVO.setCashOutCount(cashOutCount);
        return adminHomeVO;
    }

    @Override
    public UserVO getInfo(Long userId) {
        User user = baseMapper.selectById(userId);
        UserVO userVo = new UserVO();
        userVo.setUserName(user.getUserName());
        userVo.setHeadImg(user.getHeadImg());
        userVo.setNickName(user.getNickName());
        userVo.setMobile(user.getMobile());
        return userVo;
    }
}
